package com.liaozibo.jekyll.dao;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.*;
import com.qcloud.cos.transfer.MultipleFileUpload;
import com.qcloud.cos.transfer.TransferManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Repository
public class TencentCosOperationImpl implements CosOperation {

    private static final String COS_ROOT_PATH = "";
    private static final boolean RECURSIVE_UPLOAD_SUBDIRECTORY = true; // 递归上传目录下的子目录及文件


    @Autowired
    private COSClient cosClient;

    @Autowired
    private TransferManager transferManager;

    @Override
    public List<String> listBucketNames() {
        List<Bucket> buckets = cosClient.listBuckets();
        if (buckets.isEmpty()) {
            return Collections.emptyList();
        }
        List<String> bucketNameList = new ArrayList<>(buckets.size());
        for (Bucket bucket : buckets) {
            String fullName = bucket.getName();
            String bucketName = fullName.substring(0, fullName.lastIndexOf("-"));
            bucketNameList.add(bucketName);
        }
        return bucketNameList;
    }

    @Override
    public void createBucket(String bucketName) {
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
        createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
        cosClient.createBucket(createBucketRequest);
    }

    @Override
    public void enableStaticSite(String bucketName) {
        BucketWebsiteConfiguration bucketWebsiteConfiguration = new BucketWebsiteConfiguration();
        // 索引文件
        bucketWebsiteConfiguration.setIndexDocumentSuffix("index.html");
        // 路由规则
        List<RoutingRule> routingRuleList = new ArrayList<RoutingRule>();
        RoutingRule routingRule = new RoutingRule();
        RoutingRuleCondition routingRuleCondition = new RoutingRuleCondition();
        routingRuleCondition.setHttpErrorCodeReturnedEquals("404");
        routingRule.setCondition(routingRuleCondition);
        RedirectRule redirectRule = new RedirectRule();
        redirectRule.setProtocol("https");
        redirectRule.setReplaceKeyPrefixWith("404.html");
        routingRule.setRedirect(redirectRule);
        routingRuleList.add(routingRule);
        bucketWebsiteConfiguration.setRoutingRules(routingRuleList);
        cosClient.setBucketWebsiteConfiguration(bucketName, bucketWebsiteConfiguration);
    }

    @Override
    public void deleteBucket(String bucketName) {
        truncate(bucketName);
        cosClient.deleteBucket(bucketName);
    }

    @Override
    public void truncate(String bucketName) {
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
        listObjectsRequest.setBucketName(bucketName);
        listObjectsRequest.setPrefix(COS_ROOT_PATH);
        // 设置最大遍历出多少个对象, 一次 listobject 最大支持1000
        listObjectsRequest.setMaxKeys(1000);
        // 保存每次列出的结果
        ObjectListing objectListing = null;

        do {
            // 列出要删除的目录下的所有对象
            objectListing = cosClient.listObjects(listObjectsRequest);
            List<COSObjectSummary> cosObjectSummaries = objectListing.getObjectSummaries();
            if (cosObjectSummaries.isEmpty()) {
                break;
            }
            ArrayList<DeleteObjectsRequest.KeyVersion> delObjects = new ArrayList<DeleteObjectsRequest.KeyVersion>();
            for (COSObjectSummary cosObjectSummary : cosObjectSummaries) {
                delObjects.add(new DeleteObjectsRequest.KeyVersion(cosObjectSummary.getKey()));
            }

            // 批量删除对象删除
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
            deleteObjectsRequest.setKeys(delObjects);
            DeleteObjectsResult deleteObjectsResult = cosClient.deleteObjects(deleteObjectsRequest);
            List<DeleteObjectsResult.DeletedObject> deleteObjectResultArray = deleteObjectsResult.getDeletedObjects();

            // 标记下一次开始的位置
            String nextMarker = objectListing.getNextMarker();
            listObjectsRequest.setMarker(nextMarker);
        } while (objectListing.isTruncated());
    }

    @Override
    public void uploadDirectory(Path localDir, String bucketName) throws InterruptedException {
        MultipleFileUpload upload = transferManager.uploadDirectory(bucketName, COS_ROOT_PATH, localDir.toFile(), RECURSIVE_UPLOAD_SUBDIRECTORY);
        upload.waitForCompletion();
    }
}
